home *** CD-ROM | disk | FTP | other *** search
-
- ; ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ INFO ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
- ;
- ; Better write some info on this source...
- ;
- ; An Outlaw Triad intro. Introduces the Outlaw Triad team.
- ; Coded in 100% assembler and in high resolution 640*480*16.
- ; Fully commented but knowledge of vga programming is required.
- ;
- ; Major thanks go to Troop / Chiparus / Outlaw Triad! I couldn't
- ; have made this without his help. Design was done by him. Thanks!
- ;
- ; Characters are written to the screen using the Bit Mask register.
- ; Thus, only 16 MOV commands are needed to write the character to
- ; the screen which makes it pretty fast. Man, it sure was hard to
- ; code this stringwriter. I think it is up for major improvement.
- ; It's way too complex to my taste but well, I got it to work. But
- ; if you see a way to improve it, please do! In fact, this intro
- ; can be optimized quite a lot, me thinks... :-)
- ;
- ; If you decide to use this, go ahead. But don't just change the
- ; text and release it again. That would be lame. Instead, use this
- ; to learn. And, greet Outlaw Triad in your future productions.
- ; That's all. Is that cheap or what? :-)
- ;
- ; Feel like chatting? E-mail me at: comma400@tem.nhl.nl
- ;
- ; Later,
- ;
- ; -Vulture / Outlaw Triad-
- ;
- ; ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
-
- DOSSEG ; Sort segment like high level languages do
- .MODEL SMALL ; Code & data seperate segments, both < 64kB & near
- .STACK 200h ; 512 byte stack
- .286 ; Allow 286 instructions
- .DATA ; Datasegment starts here (empty)
- .CODE ; Codesegment starts here (code & data in codesegment)
- JUMPS ; Let tasm handle out of range jumps
-
- ASSUME cs:@code;ds:@code ; Let cs and ds point to code segment
-
- ; ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ Various data ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
-
- INCLUDE Text.dat ; Text to show
- INCLUDE Pal.dat ; Palette data
-
- Label Credits Byte
- DB 13,10,"▄ ▄▄ ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ▄▄ ▄"
- DB 13,10," - An Outlaw Triad Production (c) 1996 -",13,10
- DB 13,10," Code∙∙∙∙∙∙∙∙∙∙Vulture" ,13,10
- DB 13,10," -=≡ Outlaw Triad is ≡=-",13,10
- DB 13,10," Vulture(code) ■ Dazl(artist) ■ Troop(sysop) ■ Xplorer(artist)",13,10
- DB 13,10,"▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄",13,10,"$"
-
- Font_Seg DW 0 ; Font segment
- Font_Off DW 0 ; Font offset in segment
-
- Xsize EQU 1 ; 1 byte (8 pixels)
- Ysize EQU 16 ; 16 bytes
-
- TextPos EQU 80*108 ; Y position of text
-
- CharColor DB 15 ; Color of char (what else, eh? ;-) )
- Char_Off DW 0 ; Which char to start with
- Char_X DW 0
- Char_Y DW TextPos
- NewChar_X DW 0
- NewChar_Y DW 0
-
- ; ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ Code 'n stuff ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
-
- WaitVrt PROC NEAR ; Waits for vertical retrace to reduce "snow"
- mov dx,3dah
- Vrt:
- in al,dx
- test al,1000b
- jnz Vrt ; Wait until Verticle Retrace starts
- NoVrt:
- in al,dx
- test al,1000b
- jz NoVrt ; Wait until Verticle Retrace ends
- ret ; Return to main program
- WaitVrt ENDP
-
- ResetRGB PROC NEAR ; Resets number of colors to black
- mov cx,16*3 ; Number of colors (16)
- mov dx,03c8h ; Write register
- xor al,al ; Start at 0
- out dx,al ; Write to port
- inc dx ; Data register 03c9h
- xor al,al
- ResetLoop:
- out dx,al
- loop ResetLoop
- ret
- ResetRGB ENDP
-
- FadeUp PROC NEAR
- mov cx,64 ; Range from 0..63
- OuterRGB:
- xor si,si ; Real colors
- xor bx,bx ; Fading colors
- push cx
- mov cx,16*3 ; Do # colors
- InnerRGB:
- mov ah,[Palette+si] ; Load real value
- mov al,[EmptyPalette+bx] ; Load fading value
- cmp al,ah ; Compare
- je NextRGB
- inc al
- mov [EmptyPalette+bx],al
- NextRGB:
- inc si
- inc bx
- loop InnerRGB
-
- call WaitVrt
-
- lea si,EmptyPalette
- mov dx,03c8h
- xor al,al
- out dx,al
- inc dx
- mov cx,16*3 ; 16 colors (shayded)
- RGBLoop1:
- lodsb
- out dx,al
- loop RGBLoop1 ; Using a loop is saver than "rep outsb"
-
- pop cx
- loop OuterRGB ; Next run (for 0..63 rgb values)
- ret
- FadeUp ENDP
-
- FadeDown PROC NEAR
- mov cx,64 ; Range from 0..63
- OuterRGB2:
- xor si,si ; Real colors
- xor bx,bx ; Fading colors
- push cx
- mov cx,16*3 ; Do # colors
- InnerRGB2:
- mov ah,[EmptyPalette+si] ; Load real value
- cmp ah,0 ; Compare
- je NextRGB2
- dec ah
- mov [EmptyPalette+bx],ah
- NextRGB2:
- inc si
- inc bx
- loop InnerRGB2
-
- call WaitVrt
-
- lea si,EmptyPalette
- mov dx,03c8h
- xor al,al
- out dx,al
- inc dx
- mov cx,16*3 ; 16 colors (shayded)
- RGBLoop2:
- lodsb
- out dx,al
- loop RGBLoop2 ; Using a loop is saver than "rep outsb"
-
- pop cx
- loop OuterRGB2 ; Next run (for 0..63 rgb values)
- ret
- FadeDown ENDP
-
- SetColor PROC NEAR ; Needs: cx=color (0 to 15)
- mov dx,3ceh ; Graphic Controller address register port
- mov ax,0f01h ; Index 01h (enable set/reset register)
- out dx,ax
- xor al,al ; Index 00h (set/reset register)
- mov ah,cl ; Color (0 to 15)
- out dx,ax ; Set color
- ret
- SetColor ENDP
-
- TestEsc PROC NEAR
- in al,60h ; Was ESCAPE pressed ?
- cmp al,1
- je QuitNow ; Yes => quit now. . .
- ret
- TestEsc ENDP
-
- WaitHere PROC NEAR ; Simple waitroutine
- mov cx,250
- WaitLoop:
- call WaitVrt
- call TestEsc ; Check for escape
- loop WaitLoop
- ret
- ENDP WaitHere
-
- SetLines PROC NEAR
- mov cx,10 ; Color of lines
- call SetColor
- mov dx,3ceh ; Graphic Controller address register port
- mov ah,0ffh
- mov al,08h
- out dx,ax
- mov al,ah
- mov di,(80*45)+5
- mov cx,70
- rep stosb
- mov di,(80*47)+5
- mov cx,70
- rep stosb
- mov di,(80*435)+5
- mov cx,70
- rep stosb
- mov di,(80*437)+5
- mov cx,70
- rep stosb
- ret
- SetLines ENDP
-
- DeleteText PROC NEAR ; Guess what this does, eh? :-)
- xor cx,cx
- call SetColor ; Set background color
- mov di,80*50
- mov cx,80
- HoriLoop:
- push di
- mov al,0ffh
- mov bx,380 ; # of scanlines
- VertiLoop:
- mov byte ptr es:[di],al
- add di,80 ; Next scanline
- dec bx
- jnz VertiLoop
- pop di
- inc di ; Next position
- call WaitVrt
- loop HoriLoop
- ret
- DeleteText ENDP
-
- WriteChar PROC NEAR
- push ds
-
- ; === Select the char ===
- mov ds,[Word Ptr cs:Font_Seg]
- mov si,[Word Ptr cs:Font_Off] ; ds:[si] => offset to font
- xor dx,dx ; Empty dx
- mov dl,al ; dl=char to print
- shl dx,4 ; *16 (number of bytes per char)
- add si,dx ; ds:[si] points to chardata
-
- ; === Set color of char ===
- mov dx,3ceh ; Graphic Controller address register port
- mov ax,0f01h ; Index 01h (enable set/reset register)
- out dx,ax
- xor al,al ; Index 00h (set/reset register)
- mov ah,CharColor ; Color (0 to 15)
- out dx,ax ; Set color
-
- ; === Draw the char ===
- mov cx,Ysize ; If bit=0, don't draw
- YLiner:
- mov al,08h ; Index 08h (Bit Mask Register)
- mov ah,byte ptr ds:[si] ; Load the pattern (8 bits)
- out dx,ax ; Pattern selected (if bit=1 then it's drawn)
- mov al,byte ptr es:[di] ; Dummy read from vga
- mov byte ptr es:[di],ah ; Draw scanline
- add di,80 ; Next scanline (draw scanline twice)
- mov al,byte ptr es:[di]
- mov byte ptr es:[di],ah
- add di,80
- inc si
- loop YLiner
-
- pop ds
- ret
- WriteChar ENDP
-
- WriteText PROC NEAR ; Kinda complex writer... but it works :-)
- StartWrite:
- mov si,offset Text1
- add si,Char_Off ; Character offset
- inc Char_Off
- mov di,Char_Y
- add di,Char_X ; VGA position
- mov CharColor,12
-
- lodsb ; Get char (from ds:[si])
-
- cmp al,254 ; Reached end of line?
- je UpdatePos1
- cmp al,255
- je WaitNow
- cmp al,0 ; Reached end of da text?
- jne OkChar1 ; If not, do the char
- call WaitHere ; Else reset intro
- call DeleteText
- mov Char_Off,0
- mov Char_X,0
- mov Char_Y,80*125
- jmp StartWrite
-
- OkChar1:
- push si
- call WriteChar
- pop si
- inc Char_X
- jmp ShayedWrite
-
- UpdatePos1:
- mov Char_X,0
- add Char_Y,80*(Ysize*2)
- jmp ShayedWrite
-
- WaitNow:
- call WaitHere
- call DeleteText
- mov Char_X,0
- mov Char_Y,TextPos
- jmp StartWrite
-
- ShayedWrite:
- call WaitVrt
- call TestEsc
-
- mov ax,Char_X
- mov bx,Char_Y
- mov NewChar_X,ax
- mov NewChar_Y,bx ; Switch X,Y values
-
- mov CharColor,11
- mov cx,11
- MainWrite:
- push cx
- mov di,NewChar_Y
- add di,NewChar_X ; VGA position
- lodsb ; Get char (from ds:[si])
- cmp al,254 ; Reached end of line?
- je UpdatePos2
- cmp al,255
- jne LastCheck
- pop cx
- jmp StartWrite
- LastCheck:
- cmp al,0 ; Reached end of da text?
- jne OkChar2
- pop cx
- jmp StartWrite ; Jump to start of writer !!!
-
- OkChar2:
- push si
- call WriteChar
- pop si
- dec CharColor
- inc NewChar_X
- jmp Continue1
-
- UpdatePos2:
- mov NewChar_X,0
- add NewChar_Y,80*(Ysize*2)
-
- Continue1:
- pop cx
- loop MainWrite
- jmp StartWrite
-
- ret
- WriteText ENDP
-
- ; ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ Main Program ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
-
- START:
-
- mov ax,cs
- mov ds,ax ; ds points to codesegment
-
- ; === Select the charset ===
- mov al,30h ; Return seg/ofs on selected charset in BH
- mov ah,011h ; Load character generator BIOS routines
- mov bh,06h ; Select 8*16 characterset
- int 10h
- mov Font_Seg,es ; Return segment of charset
- mov Font_Off,bp ; Return offset of charset
-
- ; === Init vga ===
- mov ax,0012h ; 640x480x16 vgamode
- int 10h
-
- mov ax,0a000h
- mov es,ax ; es points to vga
-
- ; === Palette setup (code by Iguana!) ===
- mov dx,3c0h ; Create a Linear Palette instead of EGA-Palette
- xor al,al ; Index 00h & data 00h
- mov cx,16
- LinPal:
- out dx,al ; Output index.
- out dx,al ; Out to vga => value = index
- inc al
- loop LinPal
-
- mov al,34h ; Redo it, activating the VGA along
- out dx,ax
- xor al,al
- out dx,al ; Force DAC index bits p4-p7 to 0
-
- ; === Setup screen ===
- call ResetRGB
- call SetLines
- call FadeUp
-
- ; === Print text ===
- lea si,Text1
- call WriteText
-
- ; === Back to DOS ===
- QuitNow:
- call FadeDown
- mov ax,0003h
- int 10h ; Textmode
- lea dx,Credits
- mov ah,09h
- int 21h ; Write string
- mov ax,4c00h
- int 21h ; Return control to DOS
-
- END START
-
-
-
-
- ; Code by Vulture / Outlaw Triad...